/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 animation.h

	$Header: /resource_editor/animation.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined(ANIMATION_H_INCLUDED)
#define ANIMATION_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "bitmap_group.h"

// ---------------------------------------------------------
// frame order
// ---------------------------------------------------------
class t_animation_base
{
public:
	t_screen_point const&   get_base_point() const;
	int                     get_frame_count() const;
	int                     get_frame_delay() const;
	std::vector<int> const& get_frame_order() const;
	void                    set_base_point( t_screen_point const& point );
	void                    set_frame_delay( int delay );
	void                    set_frame_order( std::vector<int> const& order );
	void                    set_valid( bool x, bool y );
	bool                    x_is_valid() const;
	bool                    y_is_valid() const;
protected:
	t_screen_point   m_base_point;
	int              m_frame_delay;
	std::vector<int> m_frame_order;
	bool             m_x_is_valid;
	bool             m_y_is_valid;
};

inline t_screen_point const& t_animation_base::get_base_point() const
{
	return m_base_point;
}

inline int t_animation_base::get_frame_count() const
{
	return m_frame_order.size();
}

inline std::vector<int> const& t_animation_base::get_frame_order() const
{
	return m_frame_order;
}

inline void t_animation_base::set_base_point( t_screen_point const& point )
{
	m_base_point = point;
}

inline void t_animation_base::set_frame_order( std::vector<int> const& order )
{
	m_frame_order = order;
}

inline int t_animation_base::get_frame_delay() const
{
	return m_frame_delay;
}

inline void t_animation_base::set_frame_delay( int delay )
{
	m_frame_delay = delay;
}

inline void t_animation_base::set_valid( bool x, bool y )
{
	m_x_is_valid = x;
	m_y_is_valid = y;
}

inline bool t_animation_base::x_is_valid() const
{
	return m_x_is_valid;
}

inline bool t_animation_base::y_is_valid() const
{
	return m_y_is_valid;
}

// -------------------------------------------------------------------------
// 24 bit bitmap group with animation speed specified
// -------------------------------------------------------------------------
class t_animation_24 : public t_bitmap_group_24, public t_animation_base
{
public:
	t_animation_24();

	t_bitmap_layer_24 const* get_frame( int frame ) const;
	bool read( std::streambuf& buffer, t_progress_handler* handler );
	bool write( std::streambuf& buffer ) const;
};

inline t_bitmap_layer_24 const* t_animation_24::get_frame( int frame ) const
{
	return &at(m_frame_order[frame]);
}

inline bool read( std::streambuf& buffer, t_animation_24& animation )
{
	return animation.read( buffer, 0 );
}

// -------------------------------------------------------------------------
// 16 bit bitmap group with animation speed specified
// -------------------------------------------------------------------------
class t_animation : public t_bitmap_group, public t_animation_base 
{
public:
	t_animation();
	explicit t_animation( t_animation_24 const& source );

	t_bitmap_layer const* get_frame( int frame ) const;
};

inline t_animation::t_animation()
{
};

inline t_bitmap_layer const* t_animation::get_frame( int frame ) const
{
	return (begin() + m_frame_order[frame])->get();
}

template <>
struct t_resource_traits<t_animation_24>
{
	static char const prefix[];
	static char const extension[];
};

#endif // ANIMATION_H_INCLUDED